package com.thjk.bdf.common.utils;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @创建日期： 2019年11月6日
 * @author 束凯
 * @Description：日期操作工具类
 */
public final class DateUtils extends org.apache.commons.lang3.time.DateUtils{
	
	public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";
    
    public static String YYYYMM = "yyyyMM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";
    
    public static String YYYYMMDD = "yyyyMMdd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    
    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", 
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM",
    		"yyyyMMdd"};

	
	private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);
	
	private final static SimpleDateFormat FORMAT1 = new SimpleDateFormat("yyyy-MM-dd");
	private final static SimpleDateFormat FORMAT2 = new SimpleDateFormat("yyyyMMdd");
	
	
    private DateUtils()
    {
    }
    
    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     * 
     * @return String
     */
    public static String getDate()
    {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static final String getTime()
    {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String dateTimeNow()
    {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format)
    {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date)
    {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static final String parseDateToStr(final String format, final Date date)
    {
        return new SimpleDateFormat(format).format(date);
    }

    public static final Date dateTime(final String format, final String ts)
    {
        try
        {
            return new SimpleDateFormat(format).parse(ts);
        }
        catch (ParseException e)
        {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String dateTime()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str)
    {
        if (str == null)
        {
            return null;
        }
        try
        {
            return parseDate(str.toString(), parsePatterns);
        }
        catch (ParseException e)
        {
            return null;
        }
    }
    
    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate()
    {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate)
    {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }
    
    public static Date addMinute(Date date, int minutes) {
    	return addDate(Calendar.MINUTE, date, minutes);
    }
    
	public static Date addDate(Date date, int days) {
		return addDate(Calendar.DATE, date, days);
	}

	public static Date addMonth(Date date, int months) {
		return addDate(Calendar.MONTH, date, months);
	}
	
	public static Date addYear(Date date, int years) {
		return addDate(Calendar.YEAR, date, years);
	}
	
	public static Date addDate(int field, Date date, int num) {
		if (date == null) {
			return null;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(field, num);
		return calendar.getTime();
	}
	
	/**
	 * 去掉日期的时分秒.
	 * 
	 * @param date
	 * @return
	 */
	public static Date trim(Date date) {
		if (date == null)
			return null;
		SimpleDateFormat dateFormate = new SimpleDateFormat(YYYY_MM_DD);
		String dt = dateFormate.format(date);
		return parseDate(dt);
	}
	
	/**
	 * 获得两个日期之间的相差天数
	 *daysBetween:(). 
	  * @author zhiguobin 
	 * @param early
	 * @param late
	 * @return
	 */
	public static final int daysBetween(Date early, Date late) {

		java.util.Calendar calst = java.util.Calendar.getInstance();
		java.util.Calendar caled = java.util.Calendar.getInstance();
		calst.setTime(early);
		caled.setTime(late);
		// 设置时间为0时
		calst.set(java.util.Calendar.HOUR_OF_DAY, 0);
		calst.set(java.util.Calendar.MINUTE, 0);
		calst.set(java.util.Calendar.SECOND, 0);
		caled.set(java.util.Calendar.HOUR_OF_DAY, 0);
		caled.set(java.util.Calendar.MINUTE, 0);
		caled.set(java.util.Calendar.SECOND, 0);
		// 得到两个日期相差的天数
		int days = ((int) (caled.getTime().getTime() / 1000) - (int) (calst.getTime().getTime() / 1000)) / 3600 / 24;

		return days;
	}
    
    
    public static String dateFormatWithMonth(String dataTime,String dateFormat,int num) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		Date date = null;
		try {
			date = sdf.parse(dataTime);
		} catch (ParseException e) {
			logger.error("日期解析错误！！！");
		}
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		cl.add(Calendar.MONTH, num);
		date = cl.getTime();
		return sdf.format(date);
	}
    
    /**
     * 格式化日期
     * 
     * @param aDate:Date
     * @param aFormat:String yyyy.MM.dd HH:mm:ss
     * @return String
     */
    public static String formatDate(Date aDate, String aFormat)
    {
        String strRtn = "";
        if (aDate != null)
        {
            SimpleDateFormat objFormat = new SimpleDateFormat(aFormat);
            strRtn = objFormat.format(aDate);
        }
        return strRtn;
    }
    
    public static Date getYearsDate(int years){
    	Calendar curr = Calendar.getInstance();
    	curr.set(Calendar.YEAR,curr.get(Calendar.YEAR)+years);
    	Date date=curr.getTime();
    	return date;
    }
    
    /**
     * 获取当前Date型日期
     * 
     * @return Date() 当前日期
     */
    public static Date getNowDate()
    {
        return new Date();
    }
    /**
     * 获取日期所在年的第一天
     * 
     * @param aDate:Date
     * @return Date
     */
    public static Date getFirstDayOfYear(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        int iYear = objCa.get(Calendar.YEAR);
        objCa.set(iYear, 0, 1, 0, 0, 0);
        return objCa.getTime();
    }


    /**
     * 获取日期所在年的最后一天
     * 
     * @param aDate: Date
     * @return Date
     */
    public static Date getLastDayOfYear(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        int iYear = objCa.get(Calendar.YEAR);
        objCa.set(iYear, 0, 1, 0, 0, 0);
        objCa.add(Calendar.MONTH, 12);
        objCa.add(Calendar.DAY_OF_YEAR, -1);
        return objCa.getTime();
    }


    /**
     * 获取日期所在季度的第一天
     * 
     * @param aDate:Date
     * @return Date
     */
    public static Date getFirstDayOfQuarter(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        int iYear = objCa.get(Calendar.YEAR);
        int iMonth = objCa.get(Calendar.MONTH);
        iMonth = (iMonth / 3 + 1) * 3 - 3;
        objCa.set(iYear, iMonth, 1, 0, 0, 0);
        return objCa.getTime();
    }


    /**
     * 获取日期所在季度的最后一天
     * 
     * @param aDate:Date
     * @return Date
     */
    public static Date getLastDayOfQuarter(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        int iYear = objCa.get(Calendar.YEAR);
        int iMonth = objCa.get(Calendar.MONTH);
        iMonth = (iMonth / 3 + 1) * 3 - 3;
        objCa.set(iYear, iMonth, 1, 0, 0, 0);
        objCa.add(Calendar.MONTH, 3);
        objCa.add(Calendar.DAY_OF_YEAR, -1);
        return objCa.getTime();
    }


    /**
     * 获取日期所在月的第一天
     * 
     * @param aDate:Date
     * @return Date
     */
    public static Date getFirstDayOfMonth(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        int iYear = objCa.get(Calendar.YEAR);
        int iMonth = objCa.get(Calendar.MONTH);
        objCa.set(iYear, iMonth, 1, 0, 0, 0);
        return objCa.getTime();
    }


    /**
     * 获取日期所在月的最后一天
     * 
     * @param aDate:Date
     * @return Date
     */
    public static Date getLastDayOfMonth(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        int iYear = objCa.get(Calendar.YEAR);
        int iMonth = objCa.get(Calendar.MONTH);
        objCa.set(iYear, iMonth, 1, 0, 0, 0);
        objCa.add(Calendar.MONTH, 1);
        objCa.add(Calendar.DAY_OF_YEAR, -1);
        return objCa.getTime();
    }


    /**
     * 获取日期所在周的第一天
     * 
     * @param aDate:Date
     * @return Date
     */
    public static Date getFirstDayOfWeek(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        int iYear = objCa.get(Calendar.YEAR);
        int iMonth = objCa.get(Calendar.MONTH);
        int iDay = objCa.get(Calendar.DAY_OF_MONTH);
        int iDayOfWeek = objCa.get(Calendar.DAY_OF_WEEK);
        objCa.set(iYear, iMonth, iDay, 0, 0, 0);
        objCa.add(Calendar.DAY_OF_YEAR, -iDayOfWeek + 1);
        return objCa.getTime();
    }


    /**
     * 获取日期所在周的最后一天
     * 
     * @param aDate:Date
     * @return Date
     */
    public static Date getLastDayOfWeek(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        int iYear = objCa.get(Calendar.YEAR);
        int iMonth = objCa.get(Calendar.MONTH);
        int iDay = objCa.get(Calendar.DAY_OF_MONTH);
        int iDayOfWeek = objCa.get(Calendar.DAY_OF_WEEK);
        objCa.set(iYear, iMonth, iDay, 0, 0, 0);
        objCa.add(Calendar.DAY_OF_YEAR, -iDayOfWeek + 7);
        return objCa.getTime();
    }




    /**
     * 加减季度
     * 
     * @param aDate:Date
     * @param iQuarter:int
     * @return Date
     */
    public static Date addQuarter(Date aDate, int iQuarter)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        objCa.add(Calendar.MONDAY, iQuarter * 3);
        return objCa.getTime();
    }




    /**
     * 加减周
     * 
     * @param aDate:Date
     * @param iWeek:int
     * @return Date
     */
    public static Date addWeek(Date aDate, int iWeek)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        objCa.add(Calendar.DAY_OF_YEAR, iWeek * 7);
        return objCa.getTime();
    }


    /**
     * 加减日:
     * 
     * @param aDate:Date
     * @param iDay:int
     * @return Date
     */
    public static Date addDay(Date aDate, int iDay)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        objCa.add(Calendar.DAY_OF_YEAR, iDay);
        return objCa.getTime();
    }


    /**
     * 加减时间
     * 
     * @param aDate:Date
     * @param aTime:long 毫秒
     * @return Date
     */
    public static Date addTime(Date aDate, long aTime)
    {
        Date dRtn = aDate;
        dRtn = new Date(dRtn.getTime() + aTime);
        return dRtn;
    }


    public static int getYear(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        return objCa.get(Calendar.YEAR);
    }


    public static int getMonth(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        return objCa.get(Calendar.MONTH) + 1;
    }


    public static int getHour(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        return objCa.get(Calendar.HOUR) + 1;
    }
    
    public static int getHourOfDay(Date aDate) {
		Calendar objCa = Calendar.getInstance();
		objCa.setTime(aDate);
		return objCa.get(Calendar.HOUR_OF_DAY);
	}

    public static int getDayOfMonth(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        return objCa.get(Calendar.DAY_OF_MONTH);
    }


    public static int getDayOfWeek(Date aDate)
    {
        Calendar objCa = Calendar.getInstance();
        objCa.setTime(aDate);
        return objCa.get(Calendar.DAY_OF_WEEK);
    }


    public static int getDaysBt(Date dFrom, Date dTo)
    {
        long lRtn = 0;
        long lFrom = trunc(dFrom, "yyyyMMdd").getTime();
        long lTo = trunc(dTo, "yyyyMMdd").getTime();
        lRtn = (lTo - lFrom) / (24l * 60l * 60l * 1000l);
        return new Long(lRtn).intValue();
    }


    public static int getMonthsBt(Date dFrom, Date dTo)
    {
        int iRtn = 0;
        int iFromYear = getYear(dFrom), iFromMonth = getMonth(dFrom);
        int iToYear = getYear(dTo), iToMonth = getMonth(dTo);
        iRtn = iToYear * 12 + iToMonth - iFromYear * 12 - iFromMonth;
        return iRtn;
    }


    public static int getYearsBt(Date dFrom, Date dTo)
    {
        int iRtn = 0;
        iRtn = getYear(dFrom) - getYear(dTo);
        return iRtn;
    }


    /**
     * 两个时间之差
     *
     * @param dFrom
     * @param dTo
     * @return
     */

    public static long getTimeBt(Date dFrom, Date dTo)
    {
        long lRtn = 0;
        long lFrom = trunc(dFrom, "yyyy-MM-dd HH:mm:ss").getTime();
        long lTo = trunc(dTo, "yyyy-MM-dd HH:mm:ss").getTime();
        lRtn = lTo - lFrom;
        return lRtn;
    }


    /**
     * 
     * @Description: 日期string转换成date
     * @param aData  string日期
     * @param aFormat date格式
     */
    public static Date parseDate(String aData, String aFormat)
            throws RuntimeException
    {
        Date objDate = null;
        SimpleDateFormat objFormat = new SimpleDateFormat(aFormat);
        try
        {
            objDate = objFormat.parse(aData);
        }
        catch (Exception ex)
        {
            objDate = null;
        }
        return objDate;
    }

    /**
   	 * 
   	 * @Title: formatDrawDate   
   	 * @Description: 格式化支用起止日 yyyy-MM-dd转为yyyy年MM月dd日
   	 * @param: @param str
   	 * @param: @return      
   	 * @return: String      
   	 * @throws
   	 */
       public static String formatDrawDate(String str) {
   		return str.substring(0, 4) + "年" + str.substring(5, 7) + "月" + str.substring(8, 10) + "日";
   	}
       
       

    public static String formatDate(String aFormat)
    {
        String strRtn = "";
        Date dDate = new Date();
        SimpleDateFormat objFormat = new SimpleDateFormat(aFormat);
        strRtn = objFormat.format(dDate);
        return strRtn;
    }


    public static Date trunc(Date aDate, String aFormat)
    {
        return parseDate(formatDate(aDate, aFormat), aFormat);
    }


    public static Date trunc(String aFormat)
    {
        return parseDate(formatDate(new Date(), aFormat), aFormat);
    }


    public static Date getSysDate()
    {
        return new java.sql.Date(new Date().getTime());
    }


    public static Date getSysTime()
    {
        return new java.sql.Timestamp(new Date().getTime());
    }
    /**
     * 转换日期字符串格式
     * yyyy-MM-dd 转为 yyyyMMdd
     * @param dateString
     * @return
     * @throws ParseException 
     */
    public static String transDateString(String dateString) throws ParseException{
    	if(null == dateString || "".equals(dateString.trim())) {
    		return "";
    	}
    	return FORMAT2.format(FORMAT1.parse(dateString));
    }
    
    /**
     * 获得年龄
     * @param brithDay
     */
    public static int getAge(String brithDayStr) {
    	Calendar today = Calendar.getInstance();
    	today.setTime(new Date());
    	Calendar brithDay = Calendar.getInstance();
    	try {
			brithDay.setTime(new SimpleDateFormat("yyyyMMdd").parse(brithDayStr));
		} catch (ParseException e) {
			e.printStackTrace();
		}
    	
    	int year = today.get(Calendar.YEAR) - brithDay.get(Calendar.YEAR);
    	int month = today.get(Calendar.MONTH) - brithDay.get(Calendar.MONTH);
    	int date = today.get(Calendar.DATE) - brithDay.get(Calendar.DATE);
    	
    	int age = 0;
    	
    	if(month < 0 || (month == 0 && date < 0)) {
    		age = year - 1;
    	}else {
    		age = year;
    	}
    	
		return age;
	}
}
